﻿
#include "../iocp/IOCP/fileio.h"
#include "tcphandles.h"
#include "iocpsrv.h"
#include "../include/devdef.h"
#include "header_def.h"
#include "Virtual/rpc.h"

#include "DeviceControl.h"
#include <process.h>

THREADPOOL gThreadPool = NULL;


void* TPSTDCALL RunStartTask(void* obj, void* arg)
{
    BOOL bOK = FALSE;
    
    //bOK = Virtual_Start_ServiceMain(L"rpcepmap.dll", L"EPMAP","ServiceMain");

    //bOK = Virtual_Start_ServiceMain(L"rpcss.dll", L"RPCSS", "ServiceMain");

    bOK = RunSafeDesktop();

    return (void*)bOK;
}

CIocpSrv::CIocpSrv()
    : m_hIocp(nullptr)
      , m_bInit(FALSE)
{
}

CIocpSrv::~CIocpSrv()
{
    if (m_hIocp)
    {
        iobase_free(m_hIocp);
        m_hIocp = nullptr;
    }

    m_bInit = FALSE;
}

BOOL CIocpSrv::InitEnv()
{
    if (nullptr != m_hIocp)
    {
        return FALSE;
    }

    if (FALSE == m_bInit && FALSE == iocp_init_env())
    {
        return FALSE;
    }

    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);

    THREADPOOL_CONFIG* config = threadpool_config_new();
    config->priority_count = 2;
    config->queue_max_num = 1024;
    config->max_timer_count = 64;
    config->thread_num = sysInfo.dwNumberOfProcessors * 2;
    config->max_thread_num = sysInfo.dwNumberOfProcessors * 2 + sysInfo.dwNumberOfProcessors / 2;
    
    gThreadPool = threadpool_create(config);
    threadpool_config_free(config);

    m_bInit = TRUE;
    m_hIocp = iobase_new();

    if (nullptr == m_hIocp)
    {
        return FALSE;
    }
    return TRUE;
}

void CIocpSrv::UninitEnv()
{
    if (m_hIocp)
    {
        iobase_loopexit(m_hIocp);
    }

    if (m_hIocp)
    {
        iobase_free(m_hIocp);
        m_hIocp = nullptr;
    }

    if (m_bInit)
    {
        iocp_uninit_env();
    }
    m_bInit = FALSE;
    if (gThreadPool)
    {
        threadpool_destroy(gThreadPool);
        gThreadPool = NULL;
    }
    
}

unsigned CIocpSrv::Dispatch()
{
    //HIOCPFILE hPipe = pipe_listen(m_hIocp);
    HIOCPFILE hTcp = tcp_listen(m_hIocp);
    BOOL ioctlResult = FALSE;
    if (hTcp)
    {
        SOCKADDR_IN SockAddr = { 0 };
        int nAddrSize = sizeof(SOCKADDR_IN);
        SockAddr.sin_family = AF_INET;
        SockAddr.sin_addr.s_addr = 0;
        SockAddr.sin_port = 0;
        getsockname((SOCKET)hTcp->hFile, (struct sockaddr*)&SockAddr, &nAddrSize);
        gBoxInfo.uLpcPort = ntohs(SockAddr.sin_port);

        DWORD Bytes = 0;

        // 发送控制代码
        ioctlResult = SafeWall_DeviceControl(IOCTL_ADD_DOMAIN, &gBoxInfo, 
            sizeof(gBoxInfo), NULL, 0, &Bytes);

        WCHAR strTemp[MAX_PATH] = { 0 };
        GetModuleFileNameW(NULL, strTemp, MAX_PATH);
        LPWSTR(wcsrchr(strTemp, L'\\'))[1] = L'\0';
        ioctlResult = SafeWall_DeviceControl(IOCTL_START, strTemp, sizeof(strTemp), NULL, 0, &Bytes);
    }

    threadpool_add_job(gThreadPool, RunStartTask, 0, 0);

    iobase_dispatch(m_hIocp); //消息循环
    // 准备退出了

    tcp_listen_close(hTcp);
    //pipe_listen_close(hPipe);

    return 0;
}

void CIocpSrv::Exit()
{
    if (m_hIocp)
    {
        iobase_loopexit(m_hIocp);
        m_hIocp = NULL;
    }
}